import 'dart:convert';
import 'dart:convert' as convert;
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:orientation/orientation.dart';
import 'package:path/path.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:common/model/web_view_toast/web_view_toast.dart';
import 'package:common/page/scan_code_page.dart';
import 'package:common/page/show_picture_bottom_sheet.dart';
import 'package:common/page/t_web_view_bloc.dart';
import 'package:common/common.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';

import 'show_multiple_picture_bottom_sheet.dart';

class TWebView extends StatefulWidget {
  final String initialUrl;
  final LoadUrlType type;
  final String param;
  final String from;

  TWebView(this.initialUrl, this.type, {Key key,this.param,this.from}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _TWebViewState();
}

class _TWebViewState extends State<TWebView> {
  TWebViewBloc _bloc;
  WebViewController _webViewController;
  Set<JavascriptChannel> _javaScriptChannels;
  BuildContext _context;

  @override
  void initState() {
    super.initState();
    _javaScriptChannels = _getJavaScriptChannels();
    _bloc = TWebViewBloc(TWebViewState());
  }

  @override
  void dispose() {
    _bloc.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    _context = context;
    return BlocConsumer<TWebViewBloc, TWebViewState>(
      cubit: _bloc,
      builder: (context, state) {
        print("flutterWebView: url=${widget.initialUrl}");
        return WillPopScope(
          // ignore: missing_return
          onWillPop: () => goBack(context),
          child: Scaffold(
            appBar: AppBar(
              leading: IconButton(
                icon: Icon(Icons.arrow_back_ios, size: 20),
                onPressed: () => goBack(context),
              ),
              title: Text(
                state.title,
                style: TStyle.titleTextStyle,
              ),
              centerTitle: true,
              actions: [
                IconButton(
                  icon: Icon(Icons.close, size: 25),
                  onPressed: () {
                    OrientationPlugin.forceOrientation(DeviceOrientation.portraitUp);
                    Navigator.of(context).pop();
                    _webViewController.clearCache();
                  },
                )
              ],
            ),
            body: state.packageInfo == null
                ? Container()
                : WebView(
                    initialUrl: widget.type == LoadUrlType.URL
                        ? '${widget.initialUrl}?token=${UserBloc.token}&appVersion=${state.packageInfo.version}&from=TCoreApp${widget.from==null?'':'-${widget.from}'}&param=${widget.param}'
                        : widget.initialUrl,
                    javascriptMode: JavascriptMode.unrestricted,
                    onWebViewCreated: (controller) {
                      _webViewController = controller;
                      _bloc.webViewController = controller;
                    },
                    navigationDelegate: (request) {
                      if (request.url.startsWith("core://")) {
                        return NavigationDecision.prevent;
                      }
                      return NavigationDecision.navigate;
                    },
                    onPageFinished: (value) {
                      _webViewController.evaluateJavascript("document.title").then((result) {
                        _bloc.add(TWebViewTitleUpdateEvent(result));
                      });
                    },
                    javascriptChannels: _javaScriptChannels,
                  ),
          ),
        );
      },
      listener: (context, state) async {
        if (state.showImagePickerDialog) {
          ShowPictureBottomSheet.openModalBottomSheet(context: context).then((value) {
            if (value is PickedFile) {
              String name = basename(value.path);
              value.readAsBytes().then((bytes) {
                _webViewController
                    ?.evaluateJavascript('jsImagePickerResult("${convert.base64Encode(bytes)},$name,${bytes.length}")');
              });
            }
          });
        }
        if (state.showMultipleImagePickerDialog) {
          ShowMultiplePictureBottomSheet.openModalBottomSheet(context: context).then((value) async{
            if (value is PickedFile) {
              _webViewController
                  ?.evaluateJavascript('jsImageMultiplePickerStart("1")');
               _uploadVoucher(value.path).then((data){
                 if(data != null)
                  _webViewController?.evaluateJavascript('jsImageMultiplePickerEnd(${json.encode(data)},"0")');
                 else
                   _webViewController?.evaluateJavascript('jsImageMultiplePickerEnd("","0")');

               });
            }else{
              if(value is List<AssetEntity>){
                List<AssetEntity> _imageFiles = value;
                _webViewController
                    ?.evaluateJavascript('jsImageMultiplePickerStart("${_imageFiles.length}")');

                for(int i = 0; i < _imageFiles.length; i++){
                  print('_imageFiles[i] = ${_imageFiles[i].id} ${_imageFiles[i].title} ${_imageFiles[i].size}');
                  File f = await _imageFiles[i].file;
                  print('f = ${f.path}');
                  _uploadVoucher(f.path).then((data){
                    if(data != null)
                    _webViewController
                        ?.evaluateJavascript('jsImageMultiplePickerEnd(${json.encode(data)},"$i")');
                    else
                      _webViewController?.evaluateJavascript('jsImageMultiplePickerEnd("","0")');
                  });
                }
              }
            }
          });
        }
        if (state.openScanCodePage) {
          Map<PermissionGroup, PermissionStatus> permissions =
              await PermissionHandler().requestPermissions([PermissionGroup.camera]);
          if (permissions[PermissionGroup.camera] == PermissionStatus.granted) {
            // Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
            //   return QrCodeReaderView(
            //     scanBoxRatio: 0.7,
            //     // ignore: missing_return
            //     onScan: (value) {
            //       _webViewController?.evaluateJavascript('jsScanCodeResult("$value")');
            //     },
            //   );
            // }));
            Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
              return ScanCodePage();
            })).then((value) {
              if (value != null && value is String) {
                Fluttertoast.showToast(msg: "扫描字符串:$value");
                _webViewController?.evaluateJavascript('jsScanCodeResult("$value")');
              }else{
                Fluttertoast.showToast(msg: "扫描取消/失败");
              }
            });
          } else {
            Fluttertoast.showToast(msg: "请打开摄像头权限");
          }
        }
      },
    );
  }

  Future _uploadVoucher(String path) async {
    var name;
    var image;
    if (path != null) {
      name = path.substring(path.lastIndexOf("/") + 1, path.length);
      image = await MultipartFile.fromFile(
        path,
        filename: name,
      );
    }
    FormData formData = FormData.fromMap({"file": image});
    BaseOptions options = BaseOptions();
    options.contentType = "multipart/form-data";
    options.headers.addAll({"Authorization": UserBloc.token});
    try {
      Response response = await Dio(options).post(getUploadFileUrl(), data: formData);
      print('response = ${response.data}');
      if (response != null && response.data != null && response.data['data'] != null) {
        return response.data['data'];
      }else {
        return null;
      }
    } catch (e) {
      print('error = ${e.toString()}');
      return null;
    }
  }

  String getUploadFileUrl(){
    switch(ModuleManager().buildType){
      case BuildType.Test:
        return 'https://xxxx';
      case BuildType.Pre:
       return 'https://xxxxx';
      case BuildType.Release:
        return 'https://xxxx';
      default:  return 'https://xxxx';

    }
  }

  Future image2Base64(String path) async {
    File file = new File(path);
    List<int> imageBytes = await file.readAsBytes();
    return base64Encode(imageBytes);
  }

  Set<JavascriptChannel> _getJavaScriptChannels() {
    return Set.from([
      JavascriptChannel(
          name: "flutterScanCode",
          onMessageReceived: (JavascriptMessage message) {
            _bloc.add(TWebViewScanCodeEvent());
          }),
      JavascriptChannel(
          name: "flutterImagePicker",
          onMessageReceived: (JavascriptMessage message) {
            _bloc.add(TWebViewImagePickerEvent());
          }),
      JavascriptChannel(
          name: "flutterMultipleImagePicker",
          onMessageReceived: (JavascriptMessage message) {
            _bloc.add(TWebViewMultipleImagePickerEvent());
          }),
      JavascriptChannel(
          name: "flutterUserInfo",
          onMessageReceived: (JavascriptMessage message) {
            _bloc.add(TWebViewOnRequestUserInfoEvent());
          }),
      JavascriptChannel(
          name: "flutterGetUserInfo",
          onMessageReceived: (JavascriptMessage message) {
            _bloc.add(TWebViewOnRequestUserInfoEvent());
          }),
      JavascriptChannel(
          name: "flutterInvalidToken",
          onMessageReceived: (JavascriptMessage message) {
            _bloc.add(TWebViewOnTokenInvalidEvent());
          }),
      JavascriptChannel(
          name: "flutterDutyManagerDetail",
          onMessageReceived: (JavascriptMessage message) {
            print('message: = ${message.message}');
            if (TUtil.isEmptyString(message.message)) {
              return;
            }
            Map<String, dynamic> map;
            try {
              map = json.decode(message.message);
            } catch (e) {}
            if (map == null || !map.containsKey("dutyTaskCode")) {
              return;
            }
            _bloc.add(TWebViewDutyManagerEvent(map, _context));
          }),
      JavascriptChannel(
          name: "flutterToast",
          onMessageReceived: (JavascriptMessage message) {
            if (TUtil.isEmptyString(message.message)) {
              return;
            }
            Map<String, dynamic> map;
            try {
              map = json.decode(message.message);
            } catch (e) {}
            if (map == null || !map.containsKey("content") || TUtil.isEmptyString(map["content"])) {
              return;
            }
            _bloc.add(TWebViewToastEvent(WebViewToast.formJson(map)));
          }),
      JavascriptChannel(
          name: "flutterCopyContent",
          onMessageReceived: (JavascriptMessage message) {
            _bloc.add(TWebViewCopyContentEvent());
          }),
      JavascriptChannel(
          name: "flutterForceOrientation",
          onMessageReceived: (JavascriptMessage message) {
            Map<String, dynamic> map;
            try {
              //1竖屏 0横屏
              map = json.decode(message.message);
              if(map['orientation']!= null && map['orientation'].toString() == '0'){
                OrientationPlugin.forceOrientation(DeviceOrientation.landscapeLeft);
              }else{
                OrientationPlugin.forceOrientation(DeviceOrientation.portraitUp);
              }
            } catch (e) {
              OrientationPlugin.forceOrientation(DeviceOrientation.portraitUp);
            }
          }),
    ]);
  }

  goBack(BuildContext context) {
    if (_webViewController == null) {
      Navigator.of(context).pop();
      return;
    }
    _webViewController.canGoBack().then((value) {
      if (value) {
        _webViewController.goBack();
      } else {
        Navigator.of(context).pop();
      }
    });
  }
}
